package net.tarine.gastronomi.client.forms;

import net.tarine.gastronomi.client.AuthSingleton;
import net.tarine.gastronomi.client.IAuthenticatedWidget;
import net.tarine.gastronomi.client.IRefreshable;
import net.tarine.gastronomi.client.UiSingleton;
import net.tarine.gastronomi.client.WaitSingleton;
import net.tarine.gastronomi.client.services.GasService;
import net.tarine.gastronomi.client.services.GasServiceAsync;
import net.tarine.gastronomi.shared.AppConst;
import net.tarine.gastronomi.shared.Role;
import net.tarine.gastronomi.shared.ValidationException;
import net.tarine.gastronomi.shared.to.GasUserTo;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.FormPanel.SubmitEvent;
import com.google.gwt.user.client.ui.FormPanel.SubmitHandler;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.TextBox;

public class GasUserPopUp extends PopupPanel implements IAuthenticatedWidget {

	private final GasServiceAsync gasUserService = GWT.create(GasService.class);
	
	private GasUserTo user = null;
	
	private FormPanel form = new FormPanel();
	private String itemId = null;
	private GasUserTo item = null;
	private boolean editable = false;
	private IRefreshable parent = null;
	
	private TextBox nicknameText = null;
	private TextBox emailText = null;
	private CheckBox subscriptionCheck = null;
	private ListBox roleList = null;
	

	public GasUserPopUp(IRefreshable parent) {
		this("", parent);
	}
	public GasUserPopUp(String idUtente, IRefreshable parent) {
		super(false);
		this.itemId=idUtente;
		this.parent=parent;
		AuthSingleton.get().authorizeWidget(this);
	}
	@Override
	public void unlockWidget(GasUserTo user) {
		this.user=user;
		init();
	}
	
	
	private void init() {
		// Editing rights
		int roleId = user.getRoleId();
		if (Role.ADMIN.getId() == roleId) {
			editable=true;
		}
		//UI
		this.setModal(true);
		this.setGlassEnabled(true);
		this.add(form);
		//Load utente
		if (itemId == null) itemId = "";
		if (itemId != "") {
			loadGasUser(itemId);
		} else {
			createGasUser();
			drawGasUser();
		}
	}
	
	private void drawGasUser() {
		FlexTable table = new FlexTable();
		form.add(table);
		int r=0;
		
		HTML title = new HTML();
		title.setHTML("<h3>Utente</h3>");
		table.setWidget(r, 0, title);
		table.getFlexCellFormatter().setColSpan(r, 0, 5);
		r++;
		
		//Nickname
		table.setHTML(r, 0, "Nome");
		nicknameText = new TextBox();
		nicknameText.setValue(item.getNickname());
		nicknameText.setMaxLength(32);
		nicknameText.setEnabled(editable);
		table.setWidget(r, 1, nicknameText);
		//Ruolo
		table.setHTML(r, 3, "Ruolo");
		roleList = new ListBox();
		Role[] role = Role.values();
		for (int i=0; i<role.length; i++) {
			roleList.addItem(role[i].getDescription(), role[i].getId()+"");
			if (role[i].getId() == item.getRoleId().intValue()) {
				roleList.setItemSelected(i, true);
			}
		}
		roleList.setEnabled(editable);
		table.setWidget(r, 4, roleList);
		r++;
		
		//Email
		table.setHTML(r, 0, "Email");
		emailText = new TextBox();
		emailText.setValue(item.getEmail());
		emailText.setMaxLength(64);
		emailText.setEnabled(editable);
		table.setWidget(r, 1, emailText);
		//Descrizione
		table.setHTML(r, 3, "Risposte via email");
		subscriptionCheck = new CheckBox();
		subscriptionCheck.setValue(item.getReceiveForumEmail());
		subscriptionCheck.setEnabled(editable);
		table.setWidget(r, 4, subscriptionCheck);
		r++;
		
		HorizontalPanel buttonPanel = new HorizontalPanel();
		// Bottone SALVA
		Button submitButton = new Button("Salva", new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				form.submit();
			}
		});
		if (itemId.equals("")) {
			submitButton.setText("Crea");
		}
		submitButton.setEnabled(editable);
		buttonPanel.add(submitButton);
		
		// Bottone ANNULLA
		Button cancelButton = new Button("Annulla", new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				close();
			}
		});
		buttonPanel.add(cancelButton);
		
		table.setWidget(r,0,buttonPanel);
		table.getFlexCellFormatter().setColSpan(r, 0, 5);
		
		form.addSubmitHandler(new SubmitHandler() {
			@Override
			public void onSubmit(SubmitEvent event) {
				try {
					saveData();
					close();
				} catch (ValidationException e) {
					UiSingleton.get().addWarning(e.getMessage());
				}
			}
		});
		this.center();
		this.show();
	}
		
	private void createGasUser() {
		item = new GasUserTo();
		item.setRoleId(Role.USER.getId());
	}
	
	private void close() {
		this.hide();
	}
	
	
	
	// METODI ASINCRONI
	
	
	
	private void saveData() throws ValidationException {
		AsyncCallback<GasUserTo> callback = new AsyncCallback<GasUserTo>() {
			@Override
			public void onFailure(Throwable caught) {
				UiSingleton.get().addError(caught);
				close();
				WaitSingleton.get().stop();
			}
			@Override
			public void onSuccess(GasUserTo result) {			
				itemId = result.getId();
				parent.refresh();
				close();
				UiSingleton.get().addInfo(AppConst.MSG_SAVE_OK);
				WaitSingleton.get().stop();
			}
		};
		WaitSingleton.get().start();
		item.setNickname(nicknameText.getValue());
		item.setEmail(emailText.getValue());
		String roleString = roleList.getValue(roleList.getSelectedIndex());
		item.setRoleId(Integer.valueOf(roleString));
		item.setReceiveForumEmail(subscriptionCheck.getValue());
		gasUserService.persistGasUser(item, callback);
	}

	private void loadGasUser(String id) {
		AsyncCallback<GasUserTo> callback = new AsyncCallback<GasUserTo>() {
			@Override
			public void onFailure(Throwable caught) {
				UiSingleton.get().addError(caught);
				WaitSingleton.get().stop();
			}
			@Override
			public void onSuccess(GasUserTo result) {
				item = result;
				drawGasUser();
				WaitSingleton.get().stop();
			}
		};
		WaitSingleton.get().start();
		gasUserService.findGasUserById(id, callback);
	}
	
}
